// 日志
// json序列化和反序列化
// uuid

#pragma once
#include <ctime>
#include <string>
#include <iostream>
#include <sstream>
#include <random>
#include <cstdio>
#include <random>
#include <memory>
#include <iomanip>
#include <atomic>

#include <jsoncpp/json/json.h>

namespace zl
{
#define LDBG 0
#define LINF 1
#define LERR 2

#define LDEFAULT LDBG

#define LOG(level, format, ...) {\
    if (level >= LDEFAULT){\
        time_t t = time(NULL);\
        struct tm *lt = localtime(&t);\
        char time_tmp[32] = {0};\
        strftime(time_tmp, 31, "%m-%d %T", lt);\
        fprintf(stdout, "[%s][%s:%d] " format "\n", time_tmp, __FILE__, __LINE__, ##__VA_ARGS__);\
    }\
}
#define DLOG(format, ...) LOG(LDBG, format, ##__VA_ARGS__);
#define ILOG(format, ...) LOG(LINF, format, ##__VA_ARGS__);
#define ELOG(format, ...) LOG(LERR, format, ##__VA_ARGS__);

class JSON{
    public:
    static bool serialize(const Json::Value &val,  std::string &body)
    {
        std::stringstream ss;
        Json::StreamWriterBuilder builder;

        std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
        int ret = writer->write(val, &ss);
        if (ret == 0)
        {
            body = ss.str();
            return true;
        }
        else
        {
            ELOG("serialize error");
            return false;
        }
    }

    static bool unserialize(const std::string &body, Json::Value &val)
    {
        Json::CharReaderBuilder builder;
        std::string errs;
        std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
        bool ret =reader->parse(body.c_str(), body.c_str() + body.size(), &val, &errs);
        if (ret)
        {
            return true;
        }
        else
        {
            ELOG("unserialize failed   : %s",errs.c_str());
            return false;
        }
    }
};

class UUID
{
   public:

   static std::string uuid()
   {
    std::stringstream ss;
    //1 构造一个机器随机数对象
    std::random_device rd;
    //2 构造伪随机数对象
    std::mt19937 gen(rd());
    //3 构造限定数据范围对象
    std::uniform_int_distribution<int> dis(0,255);
    //4 生成8个随机数，按照特定格式组织成16进制数字字符串
    for(int i = 0; i < 8; i++)
    {
        if(i==4||i==6)
        ss<<"-";
        ss<<std::setw(2)<<std::setfill('0')<<std::hex<<dis(gen);
    }
    ss<<"-";
    //5 定义一个8字节序号，逐字节组织成16进制数字字符串
    //原子化1
    static std::atomic<size_t> seq(1);
    //每一次+1
    ssize_t cur=seq.fetch_add(1);
    for(int i = 7; i >= 0; i--)
    {
        if(i==5)
        ss<<"-";
        ss<<std::setw(2)<<std::setfill('0')<<std::hex<<((cur>>(i*8))&0xff);
       
    }
      return ss.str();
   }

};

}